package com.xmall.utils;

import com.xmall.annotation.Dict;
import com.xmall.define.dto.sys.DictDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

@Slf4j
@Component
public class DictUtils {

    /**
     * 字典类集合
     */
    private static Set<Class<?>> dictClassList = new HashSet<>();

    @PostConstruct
    public void init() {
        dictClassList = AnnotationUtils.getAnnotationClass(Dict.class);
    }

    /**
     * 更新字典
     */
    public static void updateDict(DictDto dictDto) {
        dictDto.getValues().forEach(dictValueDto -> setName(dictDto.getCode(), dictValueDto.getCode(), dictValueDto.getName()));
    }

    private static void setName(String enumClassName, String enumItemClassName, String newName) {
        try {
            Class<?> enumClass = findEnumClass(enumClassName);
            if(null != enumClass) {
                Object enumItemClass = findEnumItemClass(enumClass, enumItemClassName);
                if(null != enumItemClass) {
                    Method setName = enumItemClass.getClass().getMethod("setName", String.class);
                    if(null != setName) {
                        setName.invoke(enumItemClass, newName);
                    }
                }
            }
        }catch (Exception e) {
            log.error("DictUtils set name error, {}", e.getMessage());
        }
    }

    private static Class<?> findEnumClass(String enumClassName) {
        Optional<Class<?>> any = dictClassList.stream().filter(e -> e.getSimpleName().equalsIgnoreCase(enumClassName)).findAny();
        return any.isPresent() ? any.get() : null;
    }

    private static Object findEnumItemClass(Class<?> enumClass, String enumItemClassName) {
        Optional<?> any = Arrays.stream(enumClass.getEnumConstants()).filter(e -> e.toString().equalsIgnoreCase(enumItemClassName)).findAny();
        return any.isPresent() ? any.get() : null;
    }
}
